package com.errol.msgcenterclient.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.SendResult;
import com.aliyun.openservices.ons.api.bean.ProducerBean;
import com.renjia.msgcenter.autoconfig.AliYunMqProducerSelector;
import com.renjia.msgcenter.properties.MsgCenterMqProperties;
import com.renjia.uker.entity.MqMessage;
import com.renjia.uker.enums.UserTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;

/**
 * @author zhang xiao bin
 * @version v1.0
 * @date 2021/05/12
 * @since v1.1.0
 **/
@Slf4j
@Service
@ConditionalOnProperty(prefix = AliYunMqProducerSelector.PROPERTY_PREFIX, name = AliYunMqProducerSelector.ENABLE_MSG_CENTER_SERVICE, havingValue = AliYunMqProducerSelector.ENABLE_STRING)
public class MsgCenterServiceImpl implements MsgCenterService {

    @Autowired
    private MsgCenterMqProperties properties;

    @Autowired(required = false)
    @Qualifier("commonProducer")
    private ProducerBean commonProducer;

    @Autowired(required = false)
    @Qualifier("dingRobotProducer")
    private ProducerBean dingRobotProducer;

    @Override
    public boolean sendCommonMsg(@NonNull String tag, @NonNull MqMessage mqMessage) {
        if (checkParams(mqMessage)) {
            return sendCommonMsg(mqMessage, tag);
        }
        return false;
    }

    @Override
    public boolean sendCommonMsg(@NonNull String tag, @NonNull List<MqMessage> mqMessages) {
        if (mqMessages.stream().allMatch(this::checkParams)) {
            return sendCommonMsg(mqMessages, tag);
        }
        return false;
    }

    /**
     * 检查消息参数
     *
     * @param mqMessage 业务消息
     * @return true 表示校验通过
     */
    private boolean checkParams(MqMessage mqMessage) {
        if (Stream.of(mqMessage.getUserType(), mqMessage.getUserId(), mqMessage.getUsername(), mqMessage.getPhone(), mqMessage.getData()).anyMatch(Objects::isNull)) {
            log.error("业务通知消息发送失败：必要参数为空");
            return false;
        }
        return true;
    }

    /**
     * 发送业务通知
     *
     * @param data 业务消息
     * @param tag  消息场景tag
     * @return true 表示发送成功
     */
    private boolean sendCommonMsg(Object data, String tag) {
        try {
            Message message = new Message(
                    // 在控制台创建的 Topic，即该消息所属的 Topic 名称
                    properties.getCommon().getTopic(),
                    // Message Tag,
                    // 可理解为 Gmail 中的标签，对消息进行再归类，方便 Consumer 指定过滤条件在 MQ 服务器过滤
                    tag,
                    // Message Body
                    // 任何二进制形式的数据， MQ 不做任何干预，
                    // 需要 Producer 与 Consumer 协商好一致的序列化和反序列化方式
                    JSONArray.toJSONString(data).getBytes(StandardCharsets.UTF_8));
            SendResult result = commonProducer.send(message);
            boolean success = result != null && result.getMessageId() != null;
            if (!success) {
                // 发送成功的话根据消息内容到消息中心日志中查
                log.warn("业务通知消息发送失败：" + result);
            }
            return success;
        } catch (Exception e) {
            log.error("业务通知消息发送异常：", e);
            return false;
        }
    }

    @Override
    public boolean sendMsgToDingRobot(@NonNull String msg) {
        return sendMsgToDingRobot(msg, Objects.requireNonNull(properties.getDingRobot().getTag()));
    }

    @Override
    public boolean sendMsgToDingRobot(@NonNull String msg, @NonNull String tag) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("env", properties.getEnv().toUpperCase());
        jsonObject.put("msg", msg);
        MqMessage mqMessage = new MqMessage();
        mqMessage.setUserType(UserTypeEnum.INNER.getCode());
        mqMessage.setData(jsonObject);
        return sendMsgToDingRobot(mqMessage, tag);
    }

    @Override
    public boolean sendMsgToDingRobot(@NonNull MqMessage mqMessage, @NonNull String tag) {
        try {
            Message message = new Message(
                    // 在控制台创建的 Topic，即该消息所属的 Topic 名称
                    properties.getDingRobot().getTopic(),
                    // Message Tag,
                    // 可理解为 Gmail 中的标签，对消息进行再归类，方便 Consumer 指定过滤条件在 MQ 服务器过滤
                    tag,
                    // Message Body
                    // 任何二进制形式的数据， MQ 不做任何干预，
                    // 需要 Producer 与 Consumer 协商好一致的序列化和反序列化方式
                    JSONArray.toJSONString(mqMessage).getBytes(StandardCharsets.UTF_8));
            SendResult result = dingRobotProducer.send(message);
            boolean success = result != null && result.getMessageId() != null;
            if (!success) {
                // 发送成功的话根据消息内容到消息中心日志中查
                log.warn("钉钉机器人消息发送失败：" + result);
            }
            return success;
        } catch (Exception e) {
            log.error("钉钉机器人消息发送异常：", e);
            return false;
        }
    }

}
